<?php
/**
 * This file is part of DomSocketServer.
 * 
 * DomSocketServer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomSocketServer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomSocketServer.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
 * @author Oliver Leisalu
 * @package DomSocketServer
 */
class DomSocketServerClient {
	
	/**
	 * If socket is active and connected.
	 * @var Bool
	 */
	private $binded = false;
	/**
	 * Client current connection id.
	 * @var Int
	 */
	private $id;
	/**
	 * Socket
	 * @var Resource
	 */
	private $socket;
	/** 
	 * @var DomSocketServer
	 */
	private $server;
	
	/**
	 * @param DomSocketServer $server
	 */
	final public function __construct( DomSocketServer $server ) {
		$this->server = $server;
	}
	
	/**
	 * Binds socket to client
	 * @param Int $id
	 * @param Resource $socket
	 */
	final public function bind( $id, $socket ) {
		$this->socket = $socket;
		$this->id = $id;
		$this->server->log('Client['.$this->id.'] binded');
		$this->binded = true;
		
		$this->onBind();
	}
	
	/**
	 * Send message to client
	 * @param String $message
	 * @return Bool
	 */
	final public function send( $message, $sendZeroByte = true ) {
		if( $this->binded === false )
			return false;
		
		$this->server->log('<b style="color:blue">OUTPUT['.$this->id.']:</b><br />'.$message);
			
		try {
			$result = socket_write( $this->socket, $message . ($sendZeroByte ? chr(0) : NULL) );
		} catch( Exception $e ) {
			$this->closed();
		}
		
		if( $result === false ) {
			$this->log( socket_last_error($this->socket).') '.socket_strerror(socket_last_error($this->socket)) );
			$this->closed();
		}
		
		return true;
	}
	
	/**
	 * Closes socket
	 */
	final public function close() {
		$this->onClose();
		socket_shutdown( $this->socket, 2 );
		socket_close( $this->socket );
		$this->closed();
	}
	
	/**
	 * Client disconnects.
	 */
	final public function closed() {
		$this->server->destroyClient( $this );
		$this->socket = NULL;
		$this->id = NULL;
		$this->binded = false;
	}
	
	/**
	 * Get clients ip.
	 * @return String
	 */
	final public function getIp() {
		socket_getpeername($this->socket, $ip);
		return $ip;
	}
	
	/**
	 * @return Int
	 */
	final public function getId() {
		return $this->id;
	}
	/**
	 * @return DomSocketServer
	 */
	final public function getServer() {
		return $this->server;
	}
	/**
	 * @return Resource
	 */
	final public function getSocket() {
		return $this->socket;
	}
	
	// -------------------------
	// Overwritable methods
	// -------------------------
	
	/**
	 * This method will be called when client requested disconnect. Called before actually disconnecting.
	 */
	protected function onClose() {
		
	}
	/**
	 * This method will be called when client is discconnected. (Requested it or connection lost)
	 */
	protected function onClosed() {
		
	}
	/**
	 * This method will be called when client is being binded to socket. Basicly client connected.
	 */
	protected function onBind() {
		
	}
	/**
	 * This method will be called when socket state changes. Meaning some information is transferred trought socket
	 * @param String $input
	 */
	public function onData( $input ) {
		
	}
	
}
?>